package cn.wwcyc.service;

import cn.wwcyc.dao.ModbusDao;
import cn.wwcyc.domain.*;
import cn.wwcyc.exception.WWException;
import cn.wwcyc.exception.WWExceptionEnum;
import cn.wwcyc.mapper.TjHsyMapper;
import cn.wwcyc.mapper.TjSsHslMapper;
import cn.wwcyc.mapper.TjYjSsMapper;
import cn.wwcyc.mapper.TjYjXxMapper;
import cn.wwcyc.service.impl.TjSsHslServiceImpl2;
import cn.wwcyc.service.impl.TjYjSsServiceImpl;
import cn.wwcyc.utils.MQTTUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.serotonin.modbus4j.BatchRead;
import com.serotonin.modbus4j.BatchResults;
import com.serotonin.modbus4j.ModbusMaster;
import com.serotonin.modbus4j.code.DataType;
import com.serotonin.modbus4j.exception.ErrorResponseException;
import com.serotonin.modbus4j.exception.ModbusInitException;
import com.serotonin.modbus4j.exception.ModbusTransportException;
import com.serotonin.modbus4j.locator.BaseLocator;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.concurrent.*;

//实时数据采集服务
@Service
public class CjService {

    @Autowired
    TjHsyMapper tjHsyMapper;
    @Autowired
    TjSsHslMapper tjSsHslMapper;

    @Autowired
    TjYjXxMapper tjYjXxMapper;
    @Autowired
    TjYjSsMapper tjYjSsMapper;
    @Autowired
    TjYjSsService tjYjSsService;

    // 创建一个可变大小的线程池
//    Runnable timerTask = null; //定时任务
    private ScheduledExecutorService scheduler;//定时任务调度器，用于执行含水仪任务
    Runnable timerTask;
    private ScheduledFuture<?> scheduledFuture;
    private ThreadPoolExecutor executor;//线程池，用于执行含水仪任务
    private  final int CORE_POOL_SIZE = 300; // 核心线程数
    private  final int MAXIMUM_POOL_SIZE = 10000; // 最大线程数
    private  final long KEEP_ALIVE_TIME = 120L; // 线程空闲后的存活时间: 120秒
    private final int INIT_PERIOD = 60; //含水率采集频率，60秒一次
    private final int QueueSize = 20;
    //    private List<TjHsy> hsyList = new ArrayList<>();
//    private List<TjHsy> hsyList = new CopyOnWriteArrayList<>();//线程安全的list
    private List<TjYjXx> yjXxList = new CopyOnWriteArrayList<>();//线程安全的list

    private int period = INIT_PERIOD;

    synchronized public void add(TjYjXx  tjYjXx){
        yjXxList.add(tjYjXx);
    }

    synchronized public void del(TjYjXx  tjYjXx){
        yjXxList.remove(tjYjXx);
    }

    synchronized public void edit(TjYjXx  tjYjXx){
        for(int i = 0; i < yjXxList.size(); i++){
            if(yjXxList.get(i).getId().equals(tjYjXx.getId())){
                yjXxList.set(i, tjYjXx);
                break;
            }
        }
    }

    synchronized public void delById(Long  id){
        System.out.println("id=====:"+id);
        System.out.println("yjXxList:" + yjXxList);
        for (int i = 0; i < yjXxList.size(); i++) {
            if(yjXxList.get(i).getId().equals(id)){
                System.out.println("删除：" + yjXxList.get(i));
                yjXxList.remove(i);
                break;
            }
        }
    }

    synchronized public void delBatch(List<Long>  idList){
        //这个集合的迭代器不支持 remove 操作
//        Iterator<TjYjXx> iterator = yjXxList.iterator();
//        while (iterator.hasNext()) {
//            TjYjXx yj = iterator.next();
//            if (idList.contains(yj.getId())) {
//                iterator.remove();
//            }
//        }
        List<TjYjXx> yjXxList1 = new ArrayList();
        for(int i = 0; i < yjXxList.size(); i++){
            if(idList.contains(yjXxList.get(i).getId())){
                yjXxList1.add(yjXxList.get(i));
            }
        }
        yjXxList.removeAll(yjXxList1);
    }

    synchronized public void setPeriod(int period){
        this.period = period;
        if(scheduledFuture != null) {
            stopCjJob();
            startCjJob();
        }
    }
    //定时任务，一分钟取一条实时数据。
    @PostConstruct
    private void init(){
//        System.out.println("-------------HslServImpl2线程 id： " + Thread.currentThread().getId());
//        final TjSsHslServiceImpl ThisService = this;
        //获取含水仪列表
        List<TjYjXx> yjXxListFromDb = tjYjXxMapper.selectList(null);
        yjXxList.addAll(yjXxListFromDb);
//        System.out.println("开始启动含水仪任务");
        // 创建一个无界队列
        BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<>(QueueSize);

        // 创建线程池，允许核心线程在空闲时超时终止
        executor = new ThreadPoolExecutor(
                CORE_POOL_SIZE,
                MAXIMUM_POOL_SIZE,
                KEEP_ALIVE_TIME, TimeUnit.SECONDS,
                workQueue,
                new ThreadPoolExecutor.CallerRunsPolicy()); // 当队列满且线程数达到最大值时使用的策略
        // 使用ScheduledExecutorService定期提交任务到线程池scheduler，scheduler这个线程池只有一个线程，用于执行定时任务，
        // 注意，scheduler这个线程池并不用于执行含水仪任务，这个线程池其实只是一个定时器。
        //在定时任务submitTask中，将含水仪任务提交到线程池executor，executor这个线程池中的线程数量多，用于真正的并发执行各个含水仪任务。
        scheduler = Executors.newScheduledThreadPool(1);
//        ExecutorService executorService = Executors.newFixedThreadPool(1);
//        executorService
        timerTask = () -> {
            System.out.println("----------采集任务开始！！！！！" + new Date());
            if(scheduledFuture.getDelay(TimeUnit.SECONDS) < 0){//如果超时，则不执行，直接返回
                System.out.println(new Date() + "----------实时数据采集任务超时"+ scheduledFuture.getDelay(TimeUnit.SECONDS));
                return;
            }
//            try {
//                Thread.sleep(6000);
//            } catch (InterruptedException e) {
//                throw new RuntimeException(e);
//            }
            List<Future<TjYjSs>> futureYjSsList = new ArrayList<>();
            //1.这里不同步其实也可以，影响不大。(重新考虑后，觉得这里说的不对！！！必须同步)
            // 也有小概率，比如在这里遍历的中间，hsyList.size()会变，
            // 尤其是其他线程在这个时候删除了某个元素，这是就可能产生indexoutofBounds的错误。
            // 所以要加synchronized
            //这里的同步锁不能用this，必须要用CjService.this对象

            synchronized (CjService.this){
                for (int i = 0; i < yjXxList.size(); i++) {
//                    final int finalI = i;
                    TjYjXx tjYjXxSource = yjXxList.get(i);
                    TjYjXx tjYjXx = new TjYjXx();
                    //拷贝改这个对象,拷贝的原因也是因为线程同步的原因，否则可能会出现线程安全问题。
                    //只把拷贝的对象传给子线程，子线程不再需要原列表中的对象。
                    //因为在其他地方可能修改列表中的TjHsy对象，而在任务线程中要使用这个对象，为保证这个对象不出现竞争，所以为任务线程单独拷贝一份，
                    // 任务线程只使用这个拷贝的对象，原来的对象不论如何变化，都不会影响任务线程。
                    BeanUtils.copyProperties(tjYjXxSource, tjYjXx);
                    Future<TjYjSs> future = executor.submit(new Callable<TjYjSs>() {
                        @Override
                        public TjYjSs call() throws Exception {
                            //采集任务放在这里
//                        TjHsy tjHsy = hsyList.get(finalI); //这个必须放外面，不能在里面再获取，否则会报indexoutofBounds的错误
//                    System.out.println(Thread.currentThread().getName() + "正在执行含水仪任务:" + tjHsy.getJh());
                            if (tjYjXx == null) {
                                return null;
                            }
                            if (tjYjXx.getHyregtype() == null && tjYjXx.getTyregtype() == null && tjYjXx.getWdregtype() == null
                            && tjYjXx.getHsregtype() == null && tjYjXx.getJygywregtype() == null){
                                return null;
                            }
                            if(tjYjXx.getHyip() == null && tjYjXx.getTyip() == null && tjYjXx.getWdip() == null
                                    && tjYjXx.getHsip() == null && tjYjXx.getJygywip() == null){
                                return null;
                            }

                            try {
                                BatchRead<String> batch = new BatchRead<>();
                                if (tjYjXx.getHyregtype() != null && tjYjXx.getHyloc() != null && tjYjXx.getHydatatype() != null) {
                                    if( tjYjXx.getHyregtype() == 3){
                                        batch.addLocator("hy", BaseLocator.inputRegister(1, tjYjXx.getHyloc().intValue(), tjYjXx.getHydatatype().intValue()));
                                    }else if( tjYjXx.getHyregtype() == 4){
                                        batch.addLocator("hy", BaseLocator.holdingRegister(1, tjYjXx.getHyloc().intValue(), tjYjXx.getHydatatype().intValue()));
                                    }

                                }
                                if (tjYjXx.getTyregtype() != null && tjYjXx.getTyloc() != null && tjYjXx.getTydatatype() != null) {
                                     if( tjYjXx.getTyregtype() == 3){
                                         batch.addLocator("ty", BaseLocator.inputRegister(1, tjYjXx.getTyloc().intValue(), tjYjXx.getTydatatype().intValue()));
                                    }else if( tjYjXx.getTyregtype() == 4){
                                         batch.addLocator("ty", BaseLocator.holdingRegister(1, tjYjXx.getTyloc().intValue(), tjYjXx.getTydatatype().intValue()));
                                    }

                                }
                                if (tjYjXx.getWdregtype() != null && tjYjXx.getWdloc() != null && tjYjXx.getWddatatype() != null) {
                                    if( tjYjXx.getWdregtype() == 3){
                                        batch.addLocator("wd", BaseLocator.inputRegister(1, tjYjXx.getWdloc().intValue(), tjYjXx.getWddatatype().intValue()));
                                    }else if( tjYjXx.getWdregtype() == 4){
                                         batch.addLocator("wd", BaseLocator.holdingRegister(1, tjYjXx.getWdloc().intValue(), tjYjXx.getWddatatype().intValue()));
                                    }
//                                    batch.addLocator("wd", BaseLocator.holdingRegister(1, tjYjXx.getWdloc().intValue(), tjYjXx.getWddatatype().intValue()));
                                }
                                if (tjYjXx.getHsregtype() != null && tjYjXx.getHsloc() != null && tjYjXx.getHsdatatype() != null) {
                                    if( tjYjXx.getHsregtype() == 3){
                                         batch.addLocator("hs", BaseLocator.inputRegister(1, tjYjXx.getHsloc().intValue(), tjYjXx.getHsdatatype().intValue()));
                                    }else if(  tjYjXx.getHsregtype() == 4){
                                         batch.addLocator("hs", BaseLocator.holdingRegister(1, tjYjXx.getHsloc().intValue(), tjYjXx.getHsdatatype().intValue()));
                                    }
                                    //batch.addLocator("hs", BaseLocator.holdingRegister(1, tjYjXx.getHsloc().intValue(), tjYjXx.getHsdatatype().intValue()));
                                }
                                if (tjYjXx.getJygywregtype() != null && tjYjXx.getJygywloc() != null && tjYjXx.getJygywdatatype() != null) {
                                    if( tjYjXx.getJygywregtype() == 3){
                                        batch.addLocator("jygyw", BaseLocator.inputRegister(1, tjYjXx.getJygywloc().intValue(), tjYjXx.getJygywdatatype().intValue()));
                                    }else if( tjYjXx.getJygywregtype() == 4){
                                        batch.addLocator("jygyw", BaseLocator.holdingRegister(1, tjYjXx.getJygywloc().intValue(), tjYjXx.getJygywdatatype().intValue()));
                                    }
                                    //batch.addLocator("jygyw", BaseLocator.holdingRegister(1, tjYjXx.getJygywloc().intValue(), tjYjXx.getJygywdatatype().intValue()));
                                }
                                batch.setContiguousRequests(false);
                                ModbusMaster master = ModbusDao.getMaster(tjYjXx.getIp());
                                BatchResults<String> response = master.send(batch);
                                TjYjSs tjYjSs = new TjYjSs();
                                if (response != null) {
                                    //<span v-if="scope.row.valtype == 1">开关量</span>
                                    //<span v-if="scope.row.valtype == 2">16位无符号整数</span>
                                    //<span v-if="scope.row.valtype == 3">16位整数</span>
                                    //<span v-if="scope.row.valtype == 4">32位无符号整数</span>
                                    //<span v-if="scope.row.valtype == 5">32位整数</span>
                                    //<span v-if="scope.row.valtype == 8">32位float</span>

                                    if (response.getValue("hy") != null) {
                                        if (tjYjXx.getHydatatype() == 2 || tjYjXx.getHydatatype() == 3 || tjYjXx.getHydatatype() == 4 || tjYjXx.getHydatatype() == 5){
                                            if(response.getValue("hy") instanceof Long){
                                                Long hy = (Long) response.getValue("hy");
                                                tjYjSs.setJkHy(bh(hy, tjYjXx.getHybh()));
                                            }else if(response.getValue("hy") instanceof Integer){
                                                Integer hy = (Integer) response.getValue("hy");
                                                Long hyL = hy.longValue();
                                                tjYjSs.setJkHy(bh(hyL, tjYjXx.getHybh()));
                                            }
                                        } else if(tjYjXx.getHydatatype() == 8){
                                            Double hy = (Double) response.getValue("hy");
                                            tjYjSs.setJkHy(bh(hy, tjYjXx.getHybh()));
                                        }
                                    }
                                    if (response.getValue("ty") != null) {
                                        if (tjYjXx.getTydatatype() == 2 || tjYjXx.getTydatatype() == 3 || tjYjXx.getTydatatype() == 4 || tjYjXx.getTydatatype() == 5){
                                            if(response.getValue("ty") instanceof Long) {
                                                Long ty = (Long) response.getValue("ty");
                                                tjYjSs.setJkTy(bh(ty, tjYjXx.getTybh()));
                                            }else if(response.getValue("ty") instanceof Integer){
                                                Integer ty = (Integer) response.getValue("ty");
                                                Long tyL = ty.longValue();
                                                tjYjSs.setJkTy(bh(tyL, tjYjXx.getTybh()));
                                            }
                                        } else if(tjYjXx.getTydatatype() == 8){
                                            Double ty = (Double) response.getValue("ty");
                                            tjYjSs.setJkTy(bh(ty, tjYjXx.getTybh()));
                                        }
                                    }
                                    if (response.getValue("wd") != null) {
                                        if (tjYjXx.getWddatatype() == 2 || tjYjXx.getWddatatype() == 3 || tjYjXx.getWddatatype() == 4 || tjYjXx.getWddatatype() == 5){
                                            if(response.getValue("wd") instanceof Long) {
                                                Long wd = (Long) response.getValue("wd");
                                                tjYjSs.setJkWd(bh(wd, tjYjXx.getWdbh()));
                                            }else if(response.getValue("wd") instanceof Integer){
                                                Integer wd = (Integer) response.getValue("wd");
                                                Long wdL = wd.longValue();
                                                tjYjSs.setJkWd(bh(wdL, tjYjXx.getWdbh()));
                                            }
                                        } else if(tjYjXx.getWddatatype() == 8){
                                            Double wd = (Double) response.getValue("wd");
                                            tjYjSs.setJkWd(bh(wd, tjYjXx.getWdbh()));
                                        }
                                    }
                                    if (response.getValue("hs") != null) {
                                        if (tjYjXx.getHsdatatype() == 2 || tjYjXx.getHsdatatype() == 3 || tjYjXx.getHsdatatype() == 4 || tjYjXx.getHsdatatype() == 5){
                                            if(response.getValue("hs") instanceof Long) {
                                                Long hs = (Long) response.getValue("hs");
                                                tjYjSs.setHsl(bh(hs, tjYjXx.getHsbh()));
                                            }else if(response.getValue("hs") instanceof Integer){
                                                Integer hs = (Integer) response.getValue("hs");
                                                Long hsL = hs.longValue();
                                                tjYjSs.setHsl(bh(hsL, tjYjXx.getHsbh()));
                                            }
                                        } else if(tjYjXx.getHsdatatype() == 8){
                                            Double hs = (Double) response.getValue("hs");
                                            tjYjSs.setHsl(bh(hs, tjYjXx.getHsbh()));
                                        }
                                    }
                                    if (response.getValue("jygyw") != null) {
                                        if (tjYjXx.getJygywdatatype() == 2 || tjYjXx.getJygywdatatype() == 3 || tjYjXx.getJygywdatatype() == 4 || tjYjXx.getJygywdatatype() == 5){
                                            if(response.getValue("jygyw") instanceof Long) {
                                                Long jygyw = (Long) response.getValue("jygyw");
                                                tjYjSs.setJygYw(bh(jygyw, tjYjXx.getJygywbh()));
                                            }else if(response.getValue("jygyw") instanceof Integer){
                                                Integer jygyw = (Integer) response.getValue("jygyw");
                                                Long jygywL = jygyw.longValue();
                                                tjYjSs.setJygYw(bh(jygywL, tjYjXx.getJygywbh()));
                                            }
                                        } else if(tjYjXx.getJygywdatatype() == 8){
                                            Double jygyw = (Double) response.getValue("jygyw");
                                            tjYjSs.setJygYw(bh(jygyw, tjYjXx.getJygywbh()));
                                        }
                                    }
                                    tjYjSs.setId(UUID.randomUUID().toString());
                                    tjYjSs.setJh(tjYjXx.getJh());
                                    tjYjSs.setCjsj(new Date());
                                    return tjYjSs;
                                }
                                return null;
                            } catch (ErrorResponseException e) { //Illegal data address
                                //如果发生这个异常，表示其中某个寄存器地址是错误的，现在开始尝试把每个寄存器份开进行获取
//                                throw e;
                                TjYjSs tjYjSs = new TjYjSs();
                                String yjip = tjYjXx.getIp();
                                try {
                                    if (tjYjXx.getHyregtype() != null && tjYjXx.getHyloc() != null && tjYjXx.getHydatatype() != null) {
                                        String hyip = tjYjXx.getHyip() == null ? yjip : tjYjXx.getHyip();
                                        Number val = null;
                                        if( tjYjXx.getHyregtype() == 3){
//                                            batch.addLocator("hy", BaseLocator.inputRegister(1, tjYjXx.getHyloc().intValue(), tjYjXx.getHydatatype().intValue()));
                                            val = ModbusDao.readInputRegister(hyip, 1, tjYjXx.getHyloc().intValue(), tjYjXx.getHydatatype().intValue());
                                        }else if( tjYjXx.getHyregtype() == 4){
                                            val = ModbusDao.readHoldingRegister(hyip, 1, tjYjXx.getHyloc().intValue(), tjYjXx.getHydatatype().intValue());
//                                            batch.addLocator("hy", BaseLocator.holdingRegister(1, tjYjXx.getHyloc().intValue(), tjYjXx.getHydatatype().intValue()));
                                        }
                                        if (val != null) {
                                            if (tjYjXx.getHydatatype() == 2 || tjYjXx.getHydatatype() == 3 || tjYjXx.getHydatatype() == 4 || tjYjXx.getHydatatype() == 5){
                                                if(val instanceof Long){
                                                    Long hy = (Long) val;
                                                    tjYjSs.setJkHy(bh(hy, tjYjXx.getHybh()));
                                                }else if(val instanceof Integer){
                                                    Integer hy = (Integer) val;
                                                    Long hyL = hy.longValue();
                                                    tjYjSs.setJkHy(bh(hyL, tjYjXx.getHybh()));
                                                }
                                            } else if(tjYjXx.getHydatatype() == 8){
                                                Double hy = (Double) val;
                                                tjYjSs.setJkHy(bh(hy, tjYjXx.getHybh()));
                                            }
                                        }
                                    }
                                }catch(Exception e1){
                                }
                                try {
                                    if (tjYjXx.getTyregtype() != null && tjYjXx.getTyloc() != null && tjYjXx.getTydatatype() != null) {
                                        String tyip = tjYjXx.getTyip() == null ? yjip : tjYjXx.getTyip();
                                        Number val = null;
                                        if( tjYjXx.getTyregtype() == 3){
//                                            batch.addLocator("hy", BaseLocator.inputRegister(1, tjYjXx.getHyloc().intValue(), tjYjXx.getHydatatype().intValue()));
                                            val = ModbusDao.readInputRegister(tyip, 1, tjYjXx.getTyloc().intValue(), tjYjXx.getTydatatype().intValue());
                                        }else if( tjYjXx.getTyregtype() == 4){
                                            val = ModbusDao.readHoldingRegister(tyip, 1, tjYjXx.getTyloc().intValue(), tjYjXx.getTydatatype().intValue());
//                                            batch.addLocator("hy", BaseLocator.holdingRegister(1, tjYjXx.getHyloc().intValue(), tjYjXx.getHydatatype().intValue()));
                                        }
                                        if (val != null) {
                                            if (tjYjXx.getTydatatype() == 2 || tjYjXx.getTydatatype() == 3 || tjYjXx.getTydatatype() == 4 || tjYjXx.getTydatatype() == 5){
                                                if(val instanceof Long){
                                                    Long ty = (Long) val;
                                                    tjYjSs.setJkTy(bh(ty, tjYjXx.getTybh()));
                                                }else if(val instanceof Integer){
                                                    Integer ty = (Integer) val;
                                                    Long tyL = ty.longValue();
                                                    tjYjSs.setJkTy(bh(tyL, tjYjXx.getTybh()));
                                                }
                                            } else if(tjYjXx.getTydatatype() == 8){
                                                Double ty = (Double) val;
                                                tjYjSs.setJkTy(bh(ty, tjYjXx.getTybh()));
                                            }
                                        }
                                    }
                                }catch(Exception e1){
                                }
                                try {
                                    if (tjYjXx.getWdregtype() != null && tjYjXx.getWdloc() != null && tjYjXx.getWddatatype() != null) {
                                        String wdip = tjYjXx.getWdip() == null ? yjip : tjYjXx.getWdip();
                                        Number val = null;
                                        if( tjYjXx.getWdregtype() == 3){
                                            val = ModbusDao.readInputRegister(wdip, 1, tjYjXx.getWdloc().intValue(), tjYjXx.getWddatatype().intValue());
                                        }else if( tjYjXx.getWdregtype() == 4){
                                            val = ModbusDao.readHoldingRegister(wdip, 1, tjYjXx.getWdloc().intValue(), tjYjXx.getWddatatype().intValue());

                                        }
                                        if (val != null) {
                                            if (tjYjXx.getWddatatype() == 2 || tjYjXx.getWddatatype() == 3 || tjYjXx.getWddatatype() == 4 || tjYjXx.getWddatatype() == 5){
                                                if(val instanceof Long){
                                                    Long wd = (Long) val;
                                                    tjYjSs.setJkWd(bh(wd, tjYjXx.getWdbh()));
                                                }else if(val instanceof Integer){
                                                    Integer wd = (Integer) val;
                                                    Long wdL = wd.longValue();
                                                    tjYjSs.setJkWd(bh(wdL, tjYjXx.getWdbh()));
                                                }
                                            } else if(tjYjXx.getWddatatype() == 8){
                                                Double wd = (Double) val;
                                                tjYjSs.setJkWd(bh(wd, tjYjXx.getWdbh()));
                                            }
                                        }
                                    }
                                }catch(Exception e1){
                                }
                                try {
                                    if (tjYjXx.getHsregtype() != null && tjYjXx.getHsloc() != null && tjYjXx.getHsdatatype() != null) {
                                        String hsip = tjYjXx.getHsip() == null ? yjip : tjYjXx.getHsip();
                                        Number val = null;
                                        if( tjYjXx.getWdregtype() == 3){
                                            val = ModbusDao.readInputRegister(hsip, 1, tjYjXx.getHsloc().intValue(), tjYjXx.getHsdatatype().intValue());
                                        }else if( tjYjXx.getWdregtype() == 4){
                                            val = ModbusDao.readHoldingRegister(hsip, 1, tjYjXx.getHsloc().intValue(), tjYjXx.getHsdatatype().intValue());

                                        }
                                        if (val != null) {
                                            if (tjYjXx.getHsdatatype() == 2 || tjYjXx.getHsdatatype() == 3 || tjYjXx.getHsdatatype() == 4 || tjYjXx.getHsdatatype() == 5){
                                                if(val instanceof Long){
                                                    Long hs = (Long) val;
                                                    tjYjSs.setHsl(bh(hs, tjYjXx.getHsbh()));
                                                }else if(val instanceof Integer){
                                                    Integer hs = (Integer) val;
                                                    Long hsL = hs.longValue();
                                                    tjYjSs.setHsl(bh(hsL, tjYjXx.getHsbh()));
                                                }
                                            } else if(tjYjXx.getHsdatatype() == 8){
                                                Double hs = (Double) val;
                                                tjYjSs.setHsl(bh(hs, tjYjXx.getHsbh()));
                                            }
                                        }
                                    }
                                }catch(Exception e1){
                                }
                                try {
                                    if (tjYjXx.getJygywregtype() != null && tjYjXx.getJygywloc() != null && tjYjXx.getJygywdatatype() != null) {
                                        String jygywip = tjYjXx.getJygywip() == null ? yjip : tjYjXx.getJygywip();
                                        Number val = null;
                                        if( tjYjXx.getWdregtype() == 3){
                                            val = ModbusDao.readInputRegister(jygywip, 1, tjYjXx.getJygywloc().intValue(), tjYjXx.getJygywdatatype().intValue());
                                        }else if( tjYjXx.getWdregtype() == 4){
                                            val = ModbusDao.readHoldingRegister(jygywip, 1, tjYjXx.getJygywloc().intValue(), tjYjXx.getJygywdatatype().intValue());

                                        }
                                        if (val != null) {
                                            if (tjYjXx.getJygywdatatype() == 2 || tjYjXx.getJygywdatatype() == 3 || tjYjXx.getJygywdatatype() == 4 || tjYjXx.getJygywdatatype() == 5){
                                                if(val instanceof Long){
                                                    Long jygyw = (Long) val;
                                                    tjYjSs.setJygYw(bh(jygyw, tjYjXx.getJygywbh()));
                                                }else if(val instanceof Integer){
                                                    Integer jygyw = (Integer) val;
                                                    Long jygywL = jygyw.longValue();
                                                    tjYjSs.setJygYw(bh(jygywL, tjYjXx.getJygywbh()));
                                                }
                                            } else if(tjYjXx.getJygywdatatype() == 8){
                                                Double jygyw = (Double) val;
                                                tjYjSs.setJygYw(bh(jygyw, tjYjXx.getJygywbh()));
                                            }
                                        }
                                    }
                                }catch(Exception e1){
                                }
                                tjYjSs.setId(UUID.randomUUID().toString());
                                tjYjSs.setJh(tjYjXx.getJh());
                                tjYjSs.setCjsj(new Date());
//                                tjYjSsService.save(tjYjSs);
                                return tjYjSs;
                            } catch(Exception e){
                                throw e;
                            }
                        }
                    });
                    futureYjSsList.add(future);
                }
            }

            //采集完成后，获取所有采集任务线程的结果，保存至yjSsList中
            List<TjYjSs> yjSsList = new ArrayList<>();
            for (Future<TjYjSs> future : futureYjSsList) {
                try {
//                    System.out.println("future.get()"+future);
                    TjYjSs tjYjSs = future.get(period, TimeUnit.SECONDS);
                    if(tjYjSs != null){//不处理的话 null会被加入list 中
                        yjSsList.add(tjYjSs);
                    }
//                    System.out.println("----------:"+tjYjSs);
//                    tjYjSs.setCjsj(new Date());

                } catch (TimeoutException e){
//                    synchronized (TjSsHslServiceImpl2.this){
//                        scheduler.shutdownNow(); // 强制终止任务
//                        scheduler = Executors.newScheduledThreadPool(1);
//                        scheduledFuture = scheduler.scheduleAtFixedRate(timerTask, 0, period, TimeUnit.SECONDS);
//                    }
                    e.printStackTrace();
                }catch(Exception e){
                    e.printStackTrace();
                }
            }
            // 批量插入数据库中
//            System.out.println("===========开始批量插入数据库中..."+ yjSsList);
//            try {
//                tjYjSsService.save(yjSsList.get(0));
//            }catch (Exception e){
//                e.printStackTrace();
//            }
            //这里必须加try，如果发生异常不处理的话，会导致定时任务的线程结束，
            // 定时任务就只用这一个线程，那么就会导致定时就不会再执行了。
            try {
                tjYjSsService.saveBatch(yjSsList);
            }catch(Exception e){
                e.printStackTrace();
            }
            System.out.println("===========采集结束时间：" + new Date() + "  size:"+yjSsList.size());
//            scheduler.shutdown();
            //转为json
//            StringBuilder msg = new StringBuilder();
//            msg.append("[");
//            for (TjSsHsl hsl : hsls) {
//                msg.append(
//                                "{\"jh\":\"").append(hsl.getJh())
//                        .append("\",\"capacity\":").append(hsl.getCapacity())
//                        .append(",\"sshsl\":").append(hsl.getSshsl())
//                        .append(",\"cjsj\":").append(hsl.getCjsj().getTime())
//                        .append("},");
//            }
            //去掉最后一个逗号
//            if(msg.length() > 0)
//                msg.deleteCharAt(msg.length() - 1);
//            msg.append("]");
            //发送mqtt
//            MQTTUtil.sendMsg(msg);
        };
        // 每隔60秒调度一次timerTask
        scheduledFuture = scheduler.scheduleAtFixedRate(timerTask, 0, period, TimeUnit.SECONDS);
    }

    private Double bh(Long val, Long bhlx) {
        if(bhlx == 1){  //0.01d
            return val.doubleValue()/100.0;
        } else if(bhlx == 2){ //无变换
            return val.doubleValue();
        } else if(bhlx == 3) {//含水率
            return toSsHsl(val);
        }
        return val.doubleValue();//默认不变换
    }
    private Double bh(Double val, Long bhlx) {
        return val;
    }

    private Double toSsHsl(Long val){
        double n1 = val;
        // 根据不同的电容值范围计算含水率
        double n2 = n1/10;
        double n = n2 - 120;
        double data_j = 0;
        if (n <= 1.7) {
            data_j = 0;
        } else if (n > 1.7 && n < 6.7) {
            data_j = 326.24 * n - 23.64 * n * n - 486.29;
        } else if (n >= 6.7 && n < 12.7) {
            data_j = 86.31 * n + 9.66 * n * n - 373.65;
        } else if (n >= 12.7 && n < 26.7) {
            data_j = 103.47 * n + 2.02 * n * n + 673.48;
        } else if (n >= 26.7 && n < 65.5) {
            data_j = 1.38 * n * n - 19.06 * n + 4475.9;
        } else if (n >= 65.5 && n < 91.65) {
            data_j = 0.06 * n * n - 2.25 * n + 9081.2;
        } else if (n >= 91.65 && n < 98.7) {
            data_j = 119.33 * n - 0.49 * n * n + 2560.6;
        } else if (n >= 98.7 && n < 131.7) {
            data_j = 29.04 * n - 0.1 * n * n + 7648.3;
        } else if (n >= 131.7 && n < 203) {
            data_j = 10.29 * n - 0.02 * n * n + 8735.1;
        } else {
            data_j = 9999;
        }
        return data_j / 100;
    }

    synchronized public void startCjJob(){
        if(scheduledFuture != null){
            return;
        }
//        scheduler = Executors.newScheduledThreadPool(1);
        BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<>(QueueSize);

        // 创建线程池，允许核心线程在空闲时超时终止
        executor = new ThreadPoolExecutor(
                CORE_POOL_SIZE,
                MAXIMUM_POOL_SIZE,
                KEEP_ALIVE_TIME, TimeUnit.SECONDS,
                workQueue,
                new ThreadPoolExecutor.CallerRunsPolicy());
        scheduler = Executors.newScheduledThreadPool(1);

        scheduledFuture = scheduler.scheduleAtFixedRate(timerTask, 0, period, TimeUnit.SECONDS);
    }
    synchronized public void stopCjJob() {
        if(scheduledFuture == null){
            return;
        }
        executor.shutdown();
        scheduledFuture.cancel(true);//这里还需要检查，可能cancel只是取消一个任务，并不是停止线程池！！！
        scheduledFuture = null;
        //停止定时任务，不再执行定时任务
        scheduler.shutdown();

        executor = null;
        scheduler = null;
    }

    public static void main1(String[] args) {//测试RTTI
        Long l = 100L;
        Float f = 100.0f;
        Double d = 100.0;
        Integer i = 100;
        Number n = i;
        int i1 = 100;
        Number n1 = 200;
        Long l1  = (Long)n1;
    }


    public static void main(String[] args) throws ModbusInitException, ModbusTransportException, ErrorResponseException {
        CjService cjService = new CjService();
        TjYjXx tjYjXx = new TjYjXx();
        tjYjXx.setJh("卫77-27");
        tjYjXx.setIp("10.76.41.35");
        tjYjXx.setHyregtype(4L);
        tjYjXx.setHyloc(54L);
        tjYjXx.setHydatatype(2L);
        tjYjXx.setHybh(1L);
        tjYjXx.setJygywregtype(3L);
        tjYjXx.setJygywloc(1388L);
        tjYjXx.setJygywdatatype(2L);
        tjYjXx.setJygywbh(1L);



        BatchRead<String> batch = new BatchRead<>();
        if (tjYjXx.getHyregtype() != null && tjYjXx.getHyloc() != null && tjYjXx.getHydatatype() != null) {
            if( tjYjXx.getHyregtype() == 3){
                batch.addLocator("hy", BaseLocator.inputRegister(1, tjYjXx.getHyloc().intValue(), tjYjXx.getHydatatype().intValue()));
            }else if( tjYjXx.getHyregtype() == 4){
                batch.addLocator("hy", BaseLocator.holdingRegister(1, tjYjXx.getHyloc().intValue(), tjYjXx.getHydatatype().intValue()));
            }

        }
        if (tjYjXx.getTyregtype() != null && tjYjXx.getTyloc() != null && tjYjXx.getTydatatype() != null) {
            if( tjYjXx.getTyregtype() == 3){
                batch.addLocator("ty", BaseLocator.inputRegister(1, tjYjXx.getTyloc().intValue(), tjYjXx.getTydatatype().intValue()));
            }else if( tjYjXx.getTyregtype() == 4){
                batch.addLocator("ty", BaseLocator.holdingRegister(1, tjYjXx.getTyloc().intValue(), tjYjXx.getTydatatype().intValue()));
            }

        }
        if (tjYjXx.getWdregtype() != null && tjYjXx.getWdloc() != null && tjYjXx.getWddatatype() != null) {
            if( tjYjXx.getWdregtype() == 3){
                batch.addLocator("wd", BaseLocator.inputRegister(1, tjYjXx.getWdloc().intValue(), tjYjXx.getWddatatype().intValue()));
            }else if( tjYjXx.getWdregtype() == 4){
                batch.addLocator("wd", BaseLocator.holdingRegister(1, tjYjXx.getWdloc().intValue(), tjYjXx.getWddatatype().intValue()));
            }
//                                    batch.addLocator("wd", BaseLocator.holdingRegister(1, tjYjXx.getWdloc().intValue(), tjYjXx.getWddatatype().intValue()));
        }
        if (tjYjXx.getHsregtype() != null && tjYjXx.getHsloc() != null && tjYjXx.getHsdatatype() != null) {
            if( tjYjXx.getHsregtype() == 3){
                batch.addLocator("hs", BaseLocator.inputRegister(1, tjYjXx.getHsloc().intValue(), tjYjXx.getHsdatatype().intValue()));
            }else if(  tjYjXx.getHsregtype() == 4){
                batch.addLocator("hs", BaseLocator.holdingRegister(1, tjYjXx.getHsloc().intValue(), tjYjXx.getHsdatatype().intValue()));
            }
            //batch.addLocator("hs", BaseLocator.holdingRegister(1, tjYjXx.getHsloc().intValue(), tjYjXx.getHsdatatype().intValue()));
        }
        if (tjYjXx.getJygywregtype() != null && tjYjXx.getJygywloc() != null && tjYjXx.getJygywdatatype() != null) {
            if( tjYjXx.getJygywregtype() == 3){
                batch.addLocator("jygyw", BaseLocator.inputRegister(1, tjYjXx.getJygywloc().intValue(), tjYjXx.getJygywdatatype().intValue()));
            }else if( tjYjXx.getJygywregtype() == 4){
                batch.addLocator("jygyw", BaseLocator.holdingRegister(1, tjYjXx.getJygywloc().intValue(), tjYjXx.getJygywdatatype().intValue()));
            }
            //batch.addLocator("jygyw", BaseLocator.holdingRegister(1, tjYjXx.getJygywloc().intValue(), tjYjXx.getJygywdatatype().intValue()));
        }
        batch.setContiguousRequests(false);
        ModbusMaster master = ModbusDao.getMaster(tjYjXx.getIp());
        BatchResults<String> response = master.send(batch);
        TjYjSs tjYjSs = new TjYjSs();
        if (response != null) {
            //<span v-if="scope.row.valtype == 1">开关量</span>
            //<span v-if="scope.row.valtype == 2">16位无符号整数</span>
            //<span v-if="scope.row.valtype == 3">16位整数</span>
            //<span v-if="scope.row.valtype == 4">32位无符号整数</span>
            //<span v-if="scope.row.valtype == 5">32位整数</span>
            //<span v-if="scope.row.valtype == 8">32位float</span>

            if (response.getValue("hy") != null) {
                if (tjYjXx.getHydatatype() == 2 || tjYjXx.getHydatatype() == 3 || tjYjXx.getHydatatype() == 4 || tjYjXx.getHydatatype() == 5){
                    if(response.getValue("hy") instanceof Long){
                        System.out.println("hy is long");
                        Long hy = (Long) response.getValue("hy");
                        tjYjSs.setJkHy(cjService.bh(hy, tjYjXx.getHybh()));
                    }else if(response.getValue("hy") instanceof Integer){
                        System.out.println("hy is integer");
                        Integer hy = (Integer) response.getValue("hy");
                        Long hyL = hy.longValue();
                        tjYjSs.setJkHy(cjService.bh(hyL, tjYjXx.getHybh()));
                    }
                } else if(tjYjXx.getHydatatype() == 8){
                    Double hy = (Double) response.getValue("hy");
                    tjYjSs.setJkHy(cjService.bh(hy, tjYjXx.getHybh()));
                }
            }
            if (response.getValue("ty") != null) {
                if (tjYjXx.getTydatatype() == 2 || tjYjXx.getTydatatype() == 3 || tjYjXx.getTydatatype() == 4 || tjYjXx.getTydatatype() == 5){
                    if(response.getValue("ty") instanceof Long) {
                        Long ty = (Long) response.getValue("ty");
                        tjYjSs.setJkTy(cjService.bh(ty, tjYjXx.getTybh()));
                    }else if(response.getValue("ty") instanceof Integer){
                        Integer ty = (Integer) response.getValue("ty");
                        Long tyL = ty.longValue();
                        tjYjSs.setJkTy(cjService.bh(tyL, tjYjXx.getTybh()));
                    }
                } else if(tjYjXx.getTydatatype() == 8){
                    Double ty = (Double) response.getValue("ty");
                    tjYjSs.setJkTy(cjService.bh(ty, tjYjXx.getTybh()));
                }
            }
            if (response.getValue("wd") != null) {
                if (tjYjXx.getWddatatype() == 2 || tjYjXx.getWddatatype() == 3 || tjYjXx.getWddatatype() == 4 || tjYjXx.getWddatatype() == 5){
                    if(response.getValue("wd") instanceof Long) {
                        Long wd = (Long) response.getValue("wd");
                        tjYjSs.setJkWd(cjService.bh(wd, tjYjXx.getWdbh()));
                    }else if(response.getValue("wd") instanceof Integer){
                        Integer wd = (Integer) response.getValue("wd");
                        Long wdL = wd.longValue();
                        tjYjSs.setJkWd(cjService.bh(wdL, tjYjXx.getWdbh()));
                    }
                } else if(tjYjXx.getWddatatype() == 8){
                    Double wd = (Double) response.getValue("wd");
                    tjYjSs.setJkWd(cjService.bh(wd, tjYjXx.getWdbh()));
                }
            }
            if (response.getValue("hs") != null) {
                if (tjYjXx.getHsdatatype() == 2 || tjYjXx.getHsdatatype() == 3 || tjYjXx.getHsdatatype() == 4 || tjYjXx.getHsdatatype() == 5){
                    if(response.getValue("hs") instanceof Long) {
                        Long hs = (Long) response.getValue("hs");
                        tjYjSs.setHsl(cjService.bh(hs, tjYjXx.getHsbh()));
                    }else if(response.getValue("hs") instanceof Integer){
                        Integer hs = (Integer) response.getValue("hs");
                        Long hsL = hs.longValue();
                        tjYjSs.setHsl(cjService.bh(hsL, tjYjXx.getHsbh()));
                    }
                } else if(tjYjXx.getHsdatatype() == 8){
                    Double hs = (Double) response.getValue("hs");
                    tjYjSs.setHsl(cjService.bh(hs, tjYjXx.getHsbh()));
                }
            }
            if (response.getValue("jygyw") != null) {
                if (tjYjXx.getJygywdatatype() == 2 || tjYjXx.getJygywdatatype() == 3 || tjYjXx.getJygywdatatype() == 4 || tjYjXx.getJygywdatatype() == 5){
                    if(response.getValue("jygyw") instanceof Long) {
                        Long jygyw = (Long) response.getValue("jygyw");
                        tjYjSs.setJygYw(cjService.bh(jygyw, tjYjXx.getJygywbh()));
                    }else if(response.getValue("jygyw") instanceof Integer){
                        Integer jygyw = (Integer) response.getValue("jygyw");
                        Long jygywL = jygyw.longValue();
                        tjYjSs.setJygYw(cjService.bh(jygywL, tjYjXx.getJygywbh()));
                    }
                } else if(tjYjXx.getJygywdatatype() == 8){
                    Double jygyw = (Double) response.getValue("jygyw");
                    tjYjSs.setJygYw(cjService.bh(jygyw, tjYjXx.getJygywbh()));
                }
            }
            tjYjSs.setId(UUID.randomUUID().toString());
            tjYjSs.setJh(tjYjXx.getJh());
//                return tjYjSs;
            System.out.println(tjYjSs);
        }

    }
}
